<template>
  <div class="materials-page">
    <div class="page-header">
      <h1 class="page-title">学习资料</h1>
      <div class="search-box">
        <el-input
          v-model="searchQuery"
          placeholder="搜索学习资料"
          prefix-icon="el-icon-search"
          @keyup.enter.native="handleSearch"
        >
          <el-button slot="append" icon="el-icon-search" @click="handleSearch"></el-button>
        </el-input>
      </div>
    </div>

    <div class="filter-section" v-loading="subjectsLoading">
      <div class="filter-group">
        <span class="filter-label">学科：</span>
        <el-radio-group v-model="filters.subject" @change="handleFilterChange">
          <el-radio label="">全部</el-radio>
          <el-radio v-for="item in subjectOptions" :key="item.value" :label="item.value">
            {{ item.label }}
          </el-radio>
        </el-radio-group>
      </div>
      <div class="filter-group">
        <span class="filter-label">类型：</span>
        <el-radio-group v-model="filters.type" @change="handleFilterChange">
          <el-radio label="">全部</el-radio>
          <el-radio v-for="item in typeOptions" :key="item.value" :label="item.value">
            {{ item.label }}
          </el-radio>
        </el-radio-group>
      </div>
      <div class="filter-group">
        <span class="filter-label">排序：</span>
        <el-select v-model="filters.sort" @change="handleFilterChange" size="small">
          <el-option
            v-for="item in sortOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>
      </div>
    </div>

    <div class="materials-list" v-loading="loading">
      <el-row :gutter="20">
        <el-col :xs="24" :sm="12" :md="8" :lg="6" v-for="(item, index) in materialsList" :key="index">
          <div class="material-card">
            <div class="material-icon">
              <i :class="getMaterialIcon(item.type)"></i>
            </div>
            <div class="material-info">
              <h3 class="title" :title="item.title">{{ item.title }}</h3>
              <p class="desc">{{ item.description || '暂无描述' }}</p>
              <div class="meta">
                <span class="type">{{ getMaterialType(item.type) }}</span>
                <span class="size">{{ formatFileSize(item.size) }}</span>
              </div>
              <div class="stats">
                <span class="downloads"><i class="el-icon-download"></i> {{ item.downloads }}</span>
                <span class="views"><i class="el-icon-view"></i> {{ item.views }}</span>
              </div>
            </div>
            <div class="material-actions">
              <el-button type="primary" size="small" @click="previewMaterial(item)">预览</el-button>
              <el-button type="success" size="small" @click="downloadMaterial(item)">下载</el-button>
              <el-button 
                :type="item.isFavorite ? 'danger' : 'info'" 
                size="small" 
                icon="el-icon-star-off" 
                circle
                @click="toggleFavorite(item)"
              ></el-button>
            </div>
          </div>
        </el-col>
      </el-row>
      
      <!-- 空状态 -->
      <el-empty v-if="materialsList.length === 0 && !loading" description="暂无学习资料"></el-empty>
    </div>

    <div class="pagination-container" v-if="pagination.total > 0">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="pagination.page"
        :page-sizes="[12, 24, 36, 48]"
        :page-size="pagination.limit"
        layout="total, sizes, prev, pager, next, jumper"
        :total="pagination.total"
      ></el-pagination>
    </div>

    <!-- 预览对话框 -->
    <el-dialog :title="previewData.title" :visible.sync="previewDialogVisible" width="70%" top="5vh">
      <div class="preview-container" v-loading="previewLoading">
        <div v-if="previewData.type === 'pdf'" class="pdf-preview">
          <iframe :src="previewData.url" frameborder="0" width="100%" height="500px"></iframe>
        </div>
        <div v-else-if="previewData.type === 'image'" class="image-preview">
          <img :src="previewData.url" alt="预览图片" style="max-width: 100%;" />
        </div>
        <div v-else-if="previewData.type === 'video'" class="video-preview">
          <video :src="previewData.url" controls style="width: 100%"></video>
        </div>
        <div v-else class="no-preview">
          <i class="el-icon-document"></i>
          <p>该文件类型不支持在线预览，请下载后查看</p>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="previewDialogVisible = false">关闭</el-button>
        <el-button type="primary" @click="downloadMaterial(previewData)">下载</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { getMaterialList, downloadMaterial, toggleFavoriteMaterial, getMaterialDetail } from '@/api/material'
import { getAllSubjects } from '@/api/subject'

export default {
  name: 'MaterialsList',
  data() {
    return {
      searchQuery: '',
      filters: {
        subject: '',
        type: '',
        sort: 'latest'
      },
      subjectOptions: [],
      subjectsLoading: false,
      typeOptions: [
        { label: '文档', value: 'document' },
        { label: '图片', value: 'image' },
        { label: '视频', value: 'video' },
        { label: '音频', value: 'audio' },
        { label: '压缩包', value: 'archive' }
      ],
      sortOptions: [
        { label: '最新上传', value: 'latest' },
        { label: '最多下载', value: 'downloads' },
        { label: '最多浏览', value: 'views' }
      ],
      materialsList: [],
      loading: false,
      pagination: {
        page: 1,
        limit: 12,
        total: 0
      },
      previewDialogVisible: false,
      previewLoading: false,
      previewData: {
        id: '',
        title: '',
        type: '',
        url: ''
      }
    }
  },
  created() {
    this.fetchSubjects()
    this.fetchMaterials()
  },
  methods: {
    async fetchSubjects() {
      this.subjectsLoading = true
      try {
        const response = await getAllSubjects()
        this.subjectOptions = response.map(subject => ({
          label: subject.name,
          value: subject.id
        }))
      } catch (error) {
        console.error('获取学科列表失败:', error)
        this.$message.error('获取学科列表失败')
      } finally {
        this.subjectsLoading = false
      }
    },
    async fetchMaterials() {
      this.loading = true
      try {
        const params = {
          page: this.pagination.page,
          limit: this.pagination.limit,
          keyword: this.searchQuery,
          subject: this.filters.subject,
          type: this.filters.type,
          sort: this.filters.sort
        }
        
        const response = await getMaterialList(params)
        
        this.materialsList = response.records.map(material => ({
          id: material.id,
          title: material.title,
          description: material.description,
          type: material.fileType,
          size: material.fileSize,
          url: material.fileUrl,
          downloads: material.downloadCount || 0,
          views: material.viewCount || 0,
          isFavorite: material.isFavorite || false,
          createdAt: material.createdAt
        }))
        
        this.pagination.total = response.total
      } catch (error) {
        console.error('获取学习资料失败', error)
        this.$message.error('获取学习资料失败')
      } finally {
        this.loading = false
      }
    },
    handleSearch() {
      this.pagination.page = 1
      this.fetchMaterials()
    },
    handleFilterChange() {
      this.pagination.page = 1
      this.fetchMaterials()
    },
    handleSizeChange(val) {
      this.pagination.limit = val
      this.fetchMaterials()
    },
    handleCurrentChange(val) {
      this.pagination.page = val
      this.fetchMaterials()
    },
    getMaterialIcon(type) {
      const typeMap = {
        'pdf': 'el-icon-document',
        'doc': 'el-icon-document-word',
        'docx': 'el-icon-document-word',
        'xls': 'el-icon-document-excel',
        'xlsx': 'el-icon-document-excel',
        'ppt': 'el-icon-document-ppt',
        'pptx': 'el-icon-document-ppt',
        'txt': 'el-icon-document-text',
        'jpg': 'el-icon-picture',
        'jpeg': 'el-icon-picture',
        'png': 'el-icon-picture',
        'gif': 'el-icon-picture',
        'mp4': 'el-icon-video-play',
        'mp3': 'el-icon-headset',
        'zip': 'el-icon-folder',
        'rar': 'el-icon-folder'
      }
      return typeMap[type] || 'el-icon-document'
    },
    getMaterialType(type) {
      const typeMap = {
        'pdf': 'PDF文档',
        'doc': 'Word文档',
        'docx': 'Word文档',
        'xls': 'Excel表格',
        'xlsx': 'Excel表格',
        'ppt': 'PPT演示',
        'pptx': 'PPT演示',
        'txt': '文本文档',
        'jpg': '图片',
        'jpeg': '图片',
        'png': '图片',
        'gif': '图片',
        'mp4': '视频',
        'mp3': '音频',
        'zip': '压缩包',
        'rar': '压缩包'
      }
      return typeMap[type] || '未知类型'
    },
    formatFileSize(bytes) {
      if (!bytes || bytes === 0) return '0 KB'
      
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    },
    async previewMaterial(material) {
      this.previewDialogVisible = true
      this.previewLoading = true
      
      try {
        const detail = await getMaterialDetail(material.id)
        
        this.previewData = {
          id: material.id,
          title: material.title,
          type: this.getPreviewType(material.type),
          url: detail.fileUrl || material.url
        }
      } catch (error) {
        console.error('获取材料预览失败', error)
        this.$message.error('获取材料预览失败')
      } finally {
        this.previewLoading = false
      }
    },
    getPreviewType(fileType) {
      const imageTypes = ['jpg', 'jpeg', 'png', 'gif']
      const videoTypes = ['mp4']
      
      if (fileType === 'pdf') return 'pdf'
      if (imageTypes.includes(fileType)) return 'image'
      if (videoTypes.includes(fileType)) return 'video'
      
      return 'other'
    },
    async downloadMaterial(material) {
      try {
        await downloadMaterial(material.id)
        
        const link = document.createElement('a')
        link.href = material.url
        link.download = material.title
        link.target = '_blank'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        
        this.$message.success('下载成功')
        
        this.fetchMaterials()
      } catch (error) {
        console.error('下载失败', error)
        this.$message.error('下载失败')
      }
    },
    async toggleFavorite(material) {
      try {
        await toggleFavoriteMaterial(material.id)
        
        const index = this.materialsList.findIndex(item => item.id === material.id)
        if (index !== -1) {
          this.materialsList[index].isFavorite = !this.materialsList[index].isFavorite
        }
        
        this.$message.success(material.isFavorite ? '已取消收藏' : '已添加到收藏')
      } catch (error) {
        console.error('操作收藏失败', error)
        this.$message.error('操作收藏失败')
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.materials-page {
  padding: 20px;
  
  .page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    
    .page-title {
      font-size: 24px;
      font-weight: 600;
      color: #303133;
      margin: 0;
    }
    
    .search-box {
      width: 300px;
    }
  }
  
  .filter-section {
    background-color: #f5f7fa;
    padding: 15px;
    border-radius: 4px;
    margin-bottom: 20px;
    
    .filter-group {
      margin-bottom: 10px;
      display: flex;
      align-items: center;
      
      &:last-child {
        margin-bottom: 0;
      }
      
      .filter-label {
        font-weight: 600;
        margin-right: 10px;
        min-width: 60px;
      }
    }
  }
  
  .materials-list {
    min-height: 400px;
    margin-bottom: 20px;
    
    .material-card {
      background: #fff;
      border-radius: 4px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      padding: 15px;
      margin-bottom: 20px;
      height: 220px;
      display: flex;
      flex-direction: column;
      transition: all 0.3s;
      
      &:hover {
        transform: translateY(-5px);
        box-shadow: 0 4px 15px 0 rgba(0, 0, 0, 0.15);
      }
      
      .material-icon {
        text-align: center;
        margin-bottom: 10px;
        
        i {
          font-size: 40px;
          color: #409EFF;
        }
      }
      
      .material-info {
        flex: 1;
        overflow: hidden;
        
        .title {
          font-size: 16px;
          margin: 0 0 8px;
          color: #303133;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
        
        .desc {
          font-size: 12px;
          color: #606266;
          margin: 0 0 8px;
          height: 36px;
          overflow: hidden;
          text-overflow: ellipsis;
          display: -webkit-box;
          -webkit-line-clamp: 2;
          -webkit-box-orient: vertical;
        }
        
        .meta {
          display: flex;
          justify-content: space-between;
          font-size: 12px;
          color: #909399;
          margin-bottom: 8px;
        }
        
        .stats {
          display: flex;
          justify-content: space-between;
          font-size: 12px;
          color: #909399;
          
          .downloads, .views {
            display: flex;
            align-items: center;
            
            i {
              margin-right: 3px;
            }
          }
        }
      }
      
      .material-actions {
        display: flex;
        justify-content: space-between;
        margin-top: 15px;
      }
    }
  }
  
  .pagination-container {
    text-align: center;
    padding: 10px 0;
  }
  
  .preview-container {
    min-height: 300px;
    
    .no-preview {
      text-align: center;
      padding: 40px 0;
      color: #909399;
      
      i {
        font-size: 60px;
        margin-bottom: 10px;
      }
      
      p {
        font-size: 14px;
      }
    }
  }
}

@media (max-width: 768px) {
  .materials-page {
    .page-header {
      flex-direction: column;
      align-items: flex-start;
      
      .page-title {
        margin-bottom: 15px;
      }
      
      .search-box {
        width: 100%;
      }
    }
  }
}
</style> 